package it.uniroma2.sd.db;

import java.util.TreeMap;
import java.util.Vector;

//this class represents a table in a SQL philosophy
public class Table implements ITable
{
    /**
     * 
     */
    private static final long serialVersionUID = -5696697950535437527L;
    private String tableName;
    private DB db; // FIXME maybe useless...
    private TreeMap<String, IColumnsGroup> tabletreemap;

    public Table(DB dbowner, String name)
    {
	this.tableName = name;
	this.db = dbowner;
	this.tabletreemap = new TreeMap<String, IColumnsGroup>();
    }

    @Override
    public String getName()
    {
	return this.tableName;
    }

    @Override
    public void put(String rowkey, IColumn column)
    {
	IColumnsGroup colgroup;
	if ((colgroup = this.tabletreemap.get(rowkey)) != null)
	{
	    colgroup.addColumn(column);
	}
	else
	{
	    this.createRowWithColumn(rowkey, column);
	}
    }

    @Override
    public void put(String rowkey, IColumn... column)
    {
	IColumnsGroup colgroup;
	if ((colgroup = this.tabletreemap.get(rowkey)) != null)
	{
	    for (IColumn c : column)
	    {
		colgroup.addColumn(c);
	    }
	}
	else
	{
	    colgroup = this.createRowWithColumn(rowkey, column[0]);
	    for (int i = 1; i < column.length; i++)
	    {
		colgroup.addColumn(column[i]);
	    }
	}
    }

    @Override
    public IColumn getColumn(String rowkey, String columnkey)
    {
	IColumnsGroup cg;
	if ((cg = this.tabletreemap.get(rowkey)) != null)
	{
	    return cg.getColumn(columnkey);
	}
	else
	{
	    return null;
	}
    }

    @Override
    public Vector<IColumn> getAllColumns(String rowkey)
    {
	IColumnsGroup cg;
	if ((cg = this.tabletreemap.get(rowkey)) == null)
	{
	    return null;
	}
	return cg.getAllColumns();
    }

    @Override
    public boolean deleteColumn(String rowkey, String columnkey)
    // FIXME ritorna false in 2 casi: NOrow, NOcolumn. separare o usare exception
    {
	IColumnsGroup cg;
	if ((cg = this.tabletreemap.get(rowkey)) != null)
	{
	    return cg.deleteColumn(columnkey);
	}
	else
	    return false;
    }

    @Override
    public int deleteColumns(String rowkey, String... columnkey)
    // FIXME ritornare il valore della row rimossa in caso di eliminazione riga?
    // FIXME usare exception invece che numero di colonne ineistenti?
    {
	IColumnsGroup cg;
	int nonexistingcolumns = 0;
	if ((cg = this.tabletreemap.get(rowkey)) != null)
	{
	    for (String ck : columnkey)
	    {
		if (!cg.deleteColumn(ck))
		{
		    nonexistingcolumns++;
		}
	    }
	    if (cg.size() == 0)
	    {
		this.tabletreemap.remove(rowkey);
		return -nonexistingcolumns - 2; // -2 or (-nonexistingcolumns -2)
	    }
	    return nonexistingcolumns; // +nonexistingcolumns, 0 is the "all-worked" return
	}
	else
	    return -1; // no rowkey entry in this table

    }

    @Override
    public boolean deleteRow(String rowkey)
    {
	return (this.tabletreemap.remove(rowkey) != null);
    }

    /**
     * Create a new IColumnsGroup for the specified row and add the specified column
     * 
     * @param rowkey The identification name for the row
     * @param column The column to be added
     * @return The newly created IColumnsGroup
     */
    private IColumnsGroup createRowWithColumn(String rowkey, IColumn column)
    {
	IColumnsGroup cg = new ColumnsGroup();
	cg.addColumn(column);
	this.tabletreemap.put(rowkey, cg);
	return cg;
    }

    /*
     * public void addNewColumn(String rowkey, Column column) {
     * 
     * }
     * 
     * public void changeRow(String rowkey, Column column) { ColumnsGroup colgroup; if ((colgroup = this.tabletreemap.get(rowkey)) != null) // if this row does not exist create it { rowkey.concat(str) } else { colgroup.addColumn(column.getName(), column); } }
     */
}
